package com.suning.sawp.service.impl.esb;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;

import com.suning.rsc.dto.responsedto.MbfResponse;
import com.suning.rsc.httpservice.annotation.EsbEIHttpWired;
import com.suning.sawp.constants.LoggerConstants;
import com.suning.sawp.constants.PreChargeErrorConstants;
import com.suning.sawp.dto.esb.CrtPreChargeOrderReq;
import com.suning.sawp.dto.esb.CrtPreChargeOrderRtn;
import com.suning.sawp.dto.esb.PreChargePayInfo;
import com.suning.sawp.dto.esb.QueryLimitDetail;
import com.suning.sawp.dto.esb.QueryPrechargeLimitReq;
import com.suning.sawp.dto.esb.QueryPrechargeLimitRtn;
import com.suning.sawp.intf.esb.PosPreChargeEsbService;
import com.suning.sawp.intf.esb.PosPreChargeService;
import com.suning.sawp.intf.esb.PosQueryPrechargeLimitService;
import com.suning.sawp.service.util.XmlUtils;

/**
 * 
 * 调用POS现金充值接口实现类<br>
 * 〈功能详细描述〉
 * 
 * @author Wuxiao
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class PosPreChargeServiceImpl implements PosPreChargeService {

    private static final String CHARGE_TYPE_CASH = "1001";

    private static final Logger LOGGER = LoggerFactory
            .getLogger(LoggerConstants.SAWP_INTEGRATION);
    
	private PosPreChargeEsbService posPreChargeEsbService;

	private PosQueryPrechargeLimitService posQueryPrechargeLimitService;
	
	public PosPreChargeEsbService getPosPreChargeEsbService() {
		return posPreChargeEsbService;
	}

	@EsbEIHttpWired
	public void setPosPreChargeEsbService(
			PosPreChargeEsbService posPreChargeEsbService) {
		this.posPreChargeEsbService = posPreChargeEsbService;
	}

	@Override
	public CrtPreChargeOrderRtn posPrechargeOrder(String memberNo,
			String storeCode, String rechargeAmount, String casherId,
			String ruleCode, String swiftNo) {
	    Object[] args = {memberNo, storeCode, rechargeAmount, casherId, ruleCode, swiftNo};
	    LOGGER.info("PosPreChargeService.posPrechargeOrder in params: memberNo={}, storeCode={}, " +
	    		"rechargeAmount={}, casherId={}, ruleCode={}, swiftNo={}", args);
		CrtPreChargeOrderRtn ret = new CrtPreChargeOrderRtn();
		CrtPreChargeOrderReq req = new CrtPreChargeOrderReq();
		req.setCasherId(casherId);
		req.setMemberNo(memberNo);
		req.setRechargeAmount(rechargeAmount);
		req.setRuleCode(ruleCode);
		req.setSwiftNo(swiftNo);
		req.setStoreCode(storeCode);
		List<PreChargePayInfo> payList = new ArrayList<PreChargePayInfo>();
		PreChargePayInfo pay = new PreChargePayInfo();
		pay.setPayCode(CHARGE_TYPE_CASH);
		pay.setPayAmount(rechargeAmount);
		payList.add(pay);
		req.setPayInfos(payList);

		// 接口异常标识
		boolean posExceptionFlag = true;
		MbfResponse response = null;

		for (int i = 1; i <= 3; i++) {
			try {
			    LOGGER.info("现金充值调用POS创建订单第{}次请求报文{}", i,req.toString());
				response = posPreChargeEsbService.preChargePayOrder(req);
				LOGGER.info("现金充值调用POS创建订单第{}次响应报文{}", i,response.toString());
			} catch (Exception e) {
				LOGGER.error("现金充值调用POS接口创建订单充值失败", e);
			}

			// esb调用成功，并不代表业务成功
			if (XmlUtils.isEsbRespSuccess(response)) {
				posExceptionFlag = false;
				break;
			}
		}

		if (posExceptionFlag) {
			ret.setReturnCode(PreChargeErrorConstants.POS_ERR_E666);
			ret.setErrorMessage(PreChargeErrorConstants.POS_ERR_MAP
					.get(PreChargeErrorConstants.POS_ERR_E666));
			return ret;
		}

		try {
		    // 代码质量检查,增加非空判断
		    if (null != response && null != response.getOutput()) {
		        ret = (CrtPreChargeOrderRtn) response.getOutput().getMbfBody(
	                    CrtPreChargeOrderRtn.class);
		    }
		} catch (Exception e) {
			LOGGER.error("现金充值调用POS接口解析报文异常", e);
		}
		return ret;
	}

    @Override
    public QueryPrechargeLimitRtn posQueryPrechargeLimit(String storeCode,String orgCode) {
        LOGGER.info("PosPreChargeService.posQueryPrechargeLimit storeCode:{}, orgCode:{}", storeCode, orgCode);
        QueryPrechargeLimitReq req = new QueryPrechargeLimitReq();
        List<QueryLimitDetail> list = new ArrayList<QueryLimitDetail>();
        QueryLimitDetail detail = new QueryLimitDetail();
        detail.setStore(storeCode);
        detail.setSubComId(orgCode);
        list.add(detail);
        req.setSourceList(list);
        MbfResponse response = null;
        QueryPrechargeLimitRtn rtn = new QueryPrechargeLimitRtn();
        try{
            response = posQueryPrechargeLimitService.queryPrechargeCouponLimit(req);
            LOGGER.debug("现金充值调用POS查询剩余额度返回报文{}",response.toString());
        }catch(Exception e){
            LOGGER.error("现金充值调用POS查询剩余额度异常,storeCode="+storeCode, e);
           rtn.setErrFlag(PreChargeErrorConstants.QUREY_REMIAN_FAILED);
           rtn.setErrString(PreChargeErrorConstants.POS_ERR_MAP
                   .get(PreChargeErrorConstants.POS_ERR_E666));
        }
        if(null != response && XmlUtils.isEsbRespSuccess(response)){
            Document doc;
            try {
             doc = XmlUtils.getW3CDom(response.toString());
             String retFlag =  XmlUtils.getValueByXpath(doc,
                     "/MbfService/output1/errFlag");
             rtn.setErrFlag(retFlag);
             if(PreChargeErrorConstants.QUREY_REMIAN_SUCCESS.equals(retFlag)){
                 String limit =  XmlUtils.getValueByXpath(doc,
                         "/MbfService/output1/msgDetailList/availableQuato");
                 rtn.setCouponLimit(limit);
             }
             } catch (Exception e) {
                 LOGGER.error("现金充值调用POS查询剩余额度接口解析报文异常", e);
             }
         }
         return rtn;
    }

    

    public PosQueryPrechargeLimitService getPosQueryPrechargeLimitService() {
        return posQueryPrechargeLimitService;
    }
    @EsbEIHttpWired
    public void setPosQueryPrechargeLimitService(
            PosQueryPrechargeLimitService posQueryPrechargeLimitService) {
        this.posQueryPrechargeLimitService = posQueryPrechargeLimitService;
    }
    
}
